在使用 H3 的 createError 创建错误时,常见的写法如下:

        
createError({
  status: 401,
  statusText: 'Invalid refresh token',
})
        
      

如果编辑器提示 statusText 不合适,或者建议使用 message,很容易让人疑惑:明明类型定义里允许 statusText,为什么还会有这样的提示?

要回答这个问题,需要区分两件事:类型是否允许传入某个字段,以及这个字段是否适合承载当前内容。

createError 的类型定义

你贴出的类型定义是:

        
createError<unknown>(
  input:
    | string
    | (Partial<H3Error<unknown>> & {
        status?: number
        statusText?: string
      })
): H3Error<unknown>
        
      

从类型上看,createError 确实接受 status 和 statusText。因此,下面的代码在类型层面是允许的:

        
createError({
  status: 401,
  statusText: 'Unauthorized',
})
        
      

但这并不表示 statusText 适合填写任意错误信息。

statusText 和 message 的用途

通常可以这样理解:

  • status:HTTP 状态码,例如 401、404 或 500。

  • statusText:简短的状态描述,例如 Unauthorized、Not Found。

  • message:具体的错误信息,例如 Invalid refresh token。

因此,更清晰的写法是:

        
createError({
  status: 401,
  statusText: 'Unauthorized',
  message: 'Invalid refresh token',
})
        
      

这样既保留了 HTTP 状态描述,也提供了明确的业务错误信息。

如果不需要自定义状态描述,也可以省略 statusText:

        
createError({
  status: 401,
  message: 'Invalid refresh token',
})
        
      

为什么会出现关于 statusMessage 的提示?

H3 的不同版本或相关类型定义中,错误对象还可能使用 statusMessage 字段。部分工具、库或规则会建议使用 statusMessage,或提示不要将详细错误内容放在状态描述字段中。

这类提示不一定意味着 statusText 在类型上无效。它可能是在提醒:状态文本应保持简短,具体错误原因应放在 message 中。实际行为还可能受 H3 版本、框架封装或项目自定义类型影响。

因此,遇到提示时,可以检查:

  1. createError 的实际导入来源;

  2. 项目正在使用的 H3 版本;

  3. IDE 提示来自 TypeScript 类型,还是 ESLint 等代码检查规则;

  4. 项目是否对 createError 做了二次封装。

推荐写法

如果项目当前类型使用 status 和 statusText,可以采用以下写法:

        
throw createError({
  status: 401,
  statusText: 'Unauthorized',
  message: 'Invalid refresh token',
})
        
      

如果项目的类型定义要求使用 statusCode 和 statusMessage,则应以项目实际安装版本和类型为准,不要混用不同版本的字段约定。

总结

statusText 在你贴出的类型定义中是允许的,但它通常用于简短的 HTTP 状态描述;message 更适合承载具体错误信息。对于“刷新令牌无效”这类错误,推荐将状态和错误详情分开:

        
createError({
  status: 401,
  statusText: 'Unauthorized',
  message: 'Invalid refresh token',
})
        
      

这样代码意图更清楚,也能避免把详细业务信息误当成 HTTP 状态描述。